/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.web.controller.admin;

import cn.easyplatform.lang.Strings;
import cn.easyplatform.web.controller.LoginController;
import cn.easyplatform.web.controller.MainLayoutController;
import cn.easyplatform.web.controller.MobileLayoutController;
import cn.easyplatform.web.ext.cmez.CMeditor;
import cn.easyplatform.web.utils.WebUtils;
import org.dom4j.*;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.*;

import java.util.List;

/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class EditorDialog extends Window {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private PropertySetCallback<String> cb;

    private CMeditor editor;

    private int mode;

    public EditorDialog(PropertySetCallback<String> cb, String title, String width,
                        String height, int mode) {
        this.cb = cb;
        editor = new CMeditor();
        setWidth(width);
        setHeight(height);
        setTitle(title);
        this.mode = mode;
    }

    public EditorDialog(PropertySetCallback<String> cb, String title, String width,
                        String height) {
        this(cb, title, width,
                height, 0);
    }

    public EditorDialog(PropertySetCallback<String> cb, String width, String height) {
        this(cb, Labels.getLabel("admin.project.property.value") + ":", width,
                height);
    }

    public EditorDialog(PropertySetCallback<String> cb) {
        this(cb, "80%", "80%");
    }

    public void showDialog(Page page, String type, String value) {
        setClosable(true);
        setMaximizable(true);
        setBorder("normal");

        Borderlayout layout = new Borderlayout();
        Center container = new Center();
        container.setHflex("1");
        container.setVflex("1");
        editor.setMode(type);
        editor.setValue(value);
        editor.setHflex("1");
        editor.setVflex("1");
        editor.setParent(container);
        editor.setLineNumbers(true);
        container.setParent(layout);

        South south = new South();
        south.setSize("35px");
        south.setBorder("none");
        Div div = new Div();
        div.setZclass("text-center mt-2");
        div.setParent(south);
        Button cancel = new Button(Labels.getLabel("button.cancel"));
        cancel.setIconSclass("z-icon-times");
        cancel.addForward(Events.ON_CLICK, this, Events.ON_CLOSE);
        cancel.setParent(div);
        Button format = new Button(Labels.getLabel("button.beautify"));
        format.setIconSclass("z-icon-magic");
        format.setSclass("ml-2");
        format.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
            @Override
            public void onEvent(Event arg0) throws Exception {
                editor.formatAll();
            }
        });
        format.setParent(div);
        if ("eppage".equals(type)) {
            Button preview = new Button(Labels.getLabel("explorer.preview"));
            preview.setIconSclass("z-icon-eye");
            preview.setSclass("ml-2");
            preview.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
                @Override
                public void onEvent(Event arg0) throws Exception {
                    String content = (String) editor.getValue();
                    if (Strings.isBlank(content))
                        return;
                    WebUtils.preview(content, preview);
                }
            });
            preview.setParent(div);
        }
        Button ok = new Button(Labels.getLabel("button.ok"));
        ok.setIconSclass("z-icon-check");
        ok.setSclass("ml-2");
        ok.addEventListener(Events.ON_CLICK, new EventListener<Event>() {
            @Override
            public void onEvent(Event arg0) throws Exception {
                String content = (String) editor.getValue();
                try {
                    if (("eppage".equals(type) || "xml".equals(type)) && !Strings.isBlank(content)) {
                        Document doc = DocumentHelper.parseText(content);
                        if (mode > 0) {//登陆或主页模板
                            Node node = doc.selectSingleNode("//@apply");
                            if (node == null || Strings.isBlank(node.getStringValue())) {
                                if (mode == 1)
                                    throw new WrongValueException(ok, Labels.getLabel("admin.template.page.error", new String[]{LoginController.class.getName()}));
                                else if (mode == 2)
                                    throw new WrongValueException(ok, Labels.getLabel("admin.template.page.error", new String[]{MainLayoutController.class.getName()}));
                                else
                                    throw new WrongValueException(ok, Labels.getLabel("admin.template.page.error", new String[]{MobileLayoutController.class.getName()}));
                            }
                            if (mode == 1 && !LoginController.class.getName().equals(node.getStringValue()))
                                throw new WrongValueException(ok, Labels.getLabel("admin.template.page.error", new String[]{LoginController.class.getName()}));
                            if (mode == 2 && !MainLayoutController.class.getName().equals(node.getStringValue()))
                                throw new WrongValueException(ok, Labels.getLabel("admin.template.page.error", new String[]{MainLayoutController.class.getName()}));
                            if (mode == 3 && !MobileLayoutController.class.getName().equals(node.getStringValue()))
                                throw new WrongValueException(ok, Labels.getLabel("admin.template.page.error", new String[]{MobileLayoutController.class.getName()}));
                            if (mode == 1) {
                                node = doc.selectSingleNode("//textbox[@id='userId']");
                                if (node == null)
                                    throw new WrongValueException(ok, Labels.getLabel("admin.template.login.error", new String[]{"<textbox id=\"userId\"/>"}));
                                node = doc.selectSingleNode("//textbox[@id='userPassword']");
                                if (node == null)
                                    throw new WrongValueException(ok, Labels.getLabel("admin.template.login.error", new String[]{"<textbox id=\"userPassword\" type=\"password\"/>"}));
                                node = doc.selectSingleNode("//button[@id='login']");
                                if (node == null)
                                    throw new WrongValueException(ok, Labels.getLabel("admin.template.login.error", new String[]{"<button id=\"login\"/>"}));
                            }
                        }
                    }
                    cb.setValue(content);
                    EditorDialog.this.detach();
                } catch (DocumentException e) {
                    throw new WrongValueException(ok, Labels.getLabel("common.page.fomat", new String[]{e.getMessage()}));
                }
            }
        });
        ok.setParent(div);
        south.setParent(layout);
        layout.setParent(this);
        setPage(page);
        setSizable(true);
        setPosition("center,top");
        doHighlighted();
    }
}
